package org.example.redis.lock;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

/**
 * @program: rabbitmq-study
 * @description:锁客户端
 * @Version V1.0.0
 * @author: dazhi
 * @create: 2021-02-07 15:34
 **/

@Slf4j
@RequiredArgsConstructor
public class RedisLockClientImpl implements RedisLockClient {

    private final RedissonClient redissonClient;


    private RLock getLock(String lockName, LockType lockType) {
        RLock lock;
        if (LockType.REENTRANT == lockType) {
            lock = redissonClient.getLock(lockName);
        } else {
            lock = redissonClient.getFairLock(lockName);
        }
        return lock;
    }

    @Override
    public void unLock(String lockName, LockType lockType) {

        RLock lock = getLock(lockName, lockType);
        if (lock.isLocked() && lock.isHeldByCurrentThread()) {
            lock.unlock();
        }

    }

    @Override
    public <T> T lock(String lockName, LockType lockType, long waitTime, long leaseTime, TimeUnit timeUnit, Supplier<T> supplier) {
        try {
            RLock rLock = getLock(lockName, lockType);
            boolean result = rLock.tryLock(waitTime, leaseTime, timeUnit);
            if (result) {
                //rLock.lock(leaseTime, timeUnit);
                return supplier.get();
            } else {
                return (T) "获取锁失败";
            }
        } catch (Throwable e) {
            log.info("锁异常");
        } finally {
            this.unLock(lockName, lockType);
        }
        return null;
    }
}
